import type {
  RequestInterceptorCatcher,
  ResponseInterceptorCatcher,
  ErrorStatusCodeCatcher,
  ErrorApiCodeCatcher,
} from './types';

/** 统一错误提示 */
const errorNotify = async (title: string, content: string) => {
  uni.hideLoading();
  await uni.showModal({
    title,
    content: content || undefined,
    showCancel: false,
  });
};

/** 请求错误捕获 */
export const requestInterceptorCatcher: RequestInterceptorCatcher = async (
  options,
  error,
) => {
  switch (true) {
    case error.message === '登录失败':
      return {
        __error: '请求错误',
        __errMsg: '登录失败',
        __requestOptions: options,
      };
    default:
      if (options.notifyRequestError !== false) {
        await errorNotify(`${options.apiInfo}失败`, '请求失败');
      }
      return {
        __error: '请求错误',
        __errMsg: error?.message,
        __requestOptions: options,
      };
  }
};

/** 响应错误捕获 */
export const responseInterceptorCatcher: ResponseInterceptorCatcher = async (
  options,
  error,
) => {
  let __errMsg;
  switch (true) {
    case error?.message === 'request:fail timeout':
    case error?.message === 'request:fail 超时':
      __errMsg = '请求超时';
      break;
    case error?.message === 'request:fail abort':
    case error?.message === 'request:fail request:fail abort':
      return { __error: '请求终止', __requestOptions: options };
    default:
      console.log('error:');
      console.log(error.message);
      __errMsg = '响应错误';
  }
  if (options.notifyRequestError !== false) {
    await errorNotify(`${options.apiInfo}失败`, __errMsg);
  }
  return { __error: '响应错误', __errMsg, __requestOptions: options };
};

/** 异常请求状态码捕获 */
export const errorStatusCodeCatcher: ErrorStatusCodeCatcher = async (
  options,
  statusCode,
) => {
  let __errMsg;
  switch (true) {
    case statusCode === 200:
      return;
    case statusCode === 400:
      if (options.notifyResponseError !== false) {
        await errorNotify(`${options.apiInfo}失败`, '请求错误');
      }
      return {
        __error: '响应错误',
        __errMsg: '请求错误',
        __status: statusCode,
        __requestOptions: options,
      };
    case statusCode === 401:
      if (options?.authed) {
        // 重新登录之后依然不行
        __errMsg = '身份认证失败';
        break;
      } else {
        // 重新登录
        return;
      }
    case statusCode === 403:
      __errMsg = '无权限访问';
      break;
    case statusCode === 404:
      __errMsg = '访问地址不存在';
      break;
    case statusCode === 405:
      __errMsg = '请求被禁止';
      break;
    case statusCode === 408:
      __errMsg = '请求超时';
      break;
    case statusCode === 500:
      __errMsg = '服务器内部错误';
      break;
    case statusCode === 501:
      __errMsg = '服务器不支持请求功能';
      break;
    case statusCode === 502:
      __errMsg = '网关请求失败';
      break;
    case statusCode === 503:
      __errMsg = '服务器维护中';
      break;
    case statusCode === 504:
      __errMsg = '未及时从远端服务器获取请求';
      break;
    case statusCode === 505:
      __errMsg = '不支持请求的HTTP协议的版本';
      break;
    default:
      __errMsg = '';
  }
  if (options.notifyResponseError !== false) {
    await errorNotify(`${options.apiInfo}失败`, __errMsg);
  }
  return {
    __error: '响应错误',
    __errMsg,
    __status: statusCode,
    __requestOptions: options,
  };
};

/** 异常接口状态码捕获 */
export const errorApiCodeCatcher: ErrorApiCodeCatcher = async (
  options,
  result,
  response,
) => {
  const code = result.code;
  const message = result.msg;
  if (code === undefined) return;
  let __errMsg;

  switch (true) {
    case options.mock:
    case result?.code === 0:
    case options?.ignoreApiCodes?.includes?.(code):
      return;
    case result?.code === 50000:
      __errMsg = '服务器内部错误';
      break;
    case (message?.length || 51) < 50:
      __errMsg = message;
      break;
    case code !== undefined:
      __errMsg = `错误状态码 - ${code}`;
      break;
    default:
      __errMsg = '';
  }
  if (options?.notifyApiError !== false) {
    await errorNotify(`${options.apiInfo}失败`, __errMsg);
  }
  return {
    __error: '接口错误',
    __errMsg,
    __status: response.statusCode,
    __code: String(code),
    __requestOptions: options,
  };
};
